//C++函数头文件c取代.h为了更好的兼容C++
#include<iostream>
#include<cerrno>
#include<cstring>
#include<cassert>
#include<string>

//系统调用函数的头文件为.h
#include<unistd.h>
#include<sys/types.h>
#include<sys/wait.h>

int main()
{
    //让不同的进程看到同一个资源 步骤：1~3
    //任何一种进程通信中，一定要 先 保证不同进程之间看到同一份资源  步骤：4

    int pipefd[2]={0};
    //1.创建管道
    int ret=pipe(pipefd);
    if(ret<0)
    {
        std::cout<<"pipe error:"<<errno<<":"<<strerror(errno)<<std::endl;
        return 1;
    }
    //验证管道是否创建成功
    std::cout<<"pipefd[0]:"<<pipefd[0]<<std::endl;//pipefd数组下标为0的表示读端
    std::cout<<"pipefd[1]:"<<pipefd[1]<<std::endl;//pipefd数组下标为1的表示写端


    //2.创建子进程
    pid_t id=fork();
    assert(id!=-1);

    if(id==0)
    {
        //子进程

        //3.关闭不需要的fd，让父进程进行读取，让子进程去写入
        close(pipefd[0]);

        //4.开始通信 ——结合某种场景
        // const std::string nameStr="Hello ,我是子进程";
        // int cnt=1;
        // char buffer[1024]={0};

        int cnt=0;

        while(true)
        {
            char x='X';
            write(pipefd[1],&x,1);
            std::cout << "Cnt: " << ++cnt<<std::endl;
            sleep(1);
            //break;

            // snprintf(buffer,sizeof(buffer),"%s,计数器：%d，我的pid：%d",nameStr.c_str(),cnt++,getpid());
            // write(pipefd[1],buffer,strlen(buffer));
            // sleep(10);
        }

        close(pipefd[1]);
        exit(0);
    }

    //父进程

    //3.关闭不需要的fd，让父进程进行读取，让子进程去写入
    close(pipefd[1]);

    //4.开始通信    ——结合某种场景
    char buffer[1024]={0};
    int cnt=0;
    while(true)
    {
        //sleep(5);
        int n=read(pipefd[0],buffer,sizeof(buffer)-1);
        if(n>0)
        {
            buffer[n]='\0';
            std::cout<<"我是父进程，child give me message："<<buffer<<std::endl;
        }
        else if(n==0)
        {
            std::cout<<"我是父进程，读到了文件末尾"<<std::endl;
            break;
        }
        else 
        {
            std::cout<<"我是父进程，读取异常"<<std::endl;
            exit(1);
        }
        sleep(1);
        if(cnt++>5)break;
    }

    close(pipefd[0]);
    
    int status=0;
    waitpid(id,&status,0); 
    std::cout<<"sig:"<<(status&0x7F)<<std::endl;

    return 0;
}

